package form

import (
	"fmt"
	"strings"

	"github.com/micro-plat/hydra"
	"github.com/micro-plat/lib4go/errs"
	"github.com/micro-plat/lib4go/types"
)

func QueryTableData(tenantID int, tableID int, queryMap types.XMap, pageIndex, pageSize int) (types.XMaps, int, error) {
	// 获取表名
	db := hydra.C.DB().GetRegularDB()
	input := map[string]interface{}{
		"table_id":  tableID,
		"tenant_id": tenantID,
	}

	// 获取表名
	tbName, err := db.Scalar(queryTableName, input)
	if err != nil || types.GetString(tbName) == "" {
		return nil, 0, fmt.Errorf("表名不存在或查询失败,%v", err)
	}

	// 获取表字段
	columsFields, err := db.Query(queryColumnName, input)
	if err != nil || columsFields.IsEmpty() {
		return nil, 0, errs.GetDBError(int64(columsFields.Len()), err)
	}
	colums := make([]string, 0, columsFields.Len())
	for _, v := range columsFields {
		colums = append(colums, v.GetString("name"))
	}
	queryInput := map[string]interface{}{"pi": (pageIndex - 1) * pageSize, "ps": pageSize}
	// 构建查询条件
	condtiopns := make([]string, 0)
	for k, v := range queryMap {
		if types.IsEmpty(v) {
			continue
		}
		column := types.XMap{}
		for _, columnField := range columsFields {
			if k == columnField.GetString("name") {
				column = columnField
				break
			}
		}
		data, ok := v.([]interface{})
		if ok && len(data) == 2 {
			condtiopns = append(condtiopns, fmt.Sprintf("and %s > @min_%s and %s < @max_%s", k, k, k, k))
			queryInput[fmt.Sprintf("min_%s", k)] = data[0]
			queryInput[fmt.Sprintf("max_%s", k)] = data[1]
			continue
		}

		prefix := types.DecodeString(column.GetBool("is_like_query"), true, "?", "&")
		condtiopns = append(condtiopns, fmt.Sprintf("%s%s", prefix, k))
		queryInput[k] = v
	}

	// 构建查询语句
	dataSql := strings.Replace(searchDataSql, "{condition}", types.GetString(strings.Join(condtiopns, " "), "1 = 1"), -1)
	dataSql = strings.Replace(dataSql, "{table_name}", types.GetString(tbName), -1)
	dataSql = strings.Replace(dataSql, "{columns}", strings.Join(colums, ","), -1)
	rows, err := db.Query(dataSql, queryInput)
	if err != nil {
		return nil, 0, err
	}

	countSql := strings.Replace(searchCountSql, "{condition}", types.GetString(strings.Join(condtiopns, " "), "1 = 1"), -1)
	countSql = strings.Replace(countSql, "{table_name}", types.GetString(tbName), -1)
	countSql = strings.Replace(countSql, "{columns}", strings.Join(colums, ","), -1)
	vcount, err := db.Scalar(countSql, queryInput)
	if err != nil {
		return nil, 0, err
	}
	return rows, types.GetInt(vcount, 0), err

}

func QueryNameData(tenantID int, tableID int, pageIndex, pageSize int) (types.XMaps, error) {
	// 获取表名
	db := hydra.C.DB().GetRegularDB()
	input := map[string]interface{}{
		"table_id":  tableID,
		"tenant_id": tenantID,
	}

	// 获取表名
	tbName, err := db.Scalar(queryTableName, input)
	if err != nil || types.GetString(tbName) == "" {
		return nil, fmt.Errorf("表名不存在或查询失败,%v", err)
	}

	// 获取表字段
	columsFields, err := db.Query(queryDictNames, input)
	if err != nil {
		return nil, err
	}
	if columsFields.Len() == 0 {
		return nil, errs.NewError(406, "表没有字典字段")
	}
	if columsFields.Len() > 2 {
		return nil, errs.NewError(406, "表有多个字典字段")
	}
	colums := make([]string, 0, columsFields.Len())
	colums = append(colums, fmt.Sprintf("'%d' as type", tableID))
	for _, v := range columsFields {
		isPk := v.GetBool("is_pk", false)
		isDictLabel := v.GetBool("is_dict_label", false)
		var nickName string
		switch {
		case isPk:
			nickName = "value"
		case isDictLabel:
			nickName = "label"
		default:
			return nil, errs.NewError(406, "字典字段配置错误")
		}
		colums = append(colums, fmt.Sprintf("%s as %s", v.GetString("name"), nickName))
	}
	queryInput := map[string]interface{}{"pi": (pageIndex - 1) * pageSize, "ps": pageSize}
	// 构建查询语句
	searchDataSql := strings.Replace(searchDataSql, "{condition}", "1 = 1", -1)
	searchDataSql = strings.Replace(searchDataSql, "{table_name}", types.GetString(tbName), -1)
	searchDataSql = strings.Replace(searchDataSql, "{columns}", strings.Join(colums, ","), -1)

	rows, err := db.Query(searchDataSql, queryInput)
	return rows, err

}

func InsertTableData(tenantID int, tableID int, insertMap types.XMap) (int64, error) {
	// 获取表名
	db := hydra.C.DB().GetRegularDB()
	input := map[string]interface{}{
		"table_id":  tableID,
		"tenant_id": tenantID,
	}

	// 获取表名
	tbName, err := db.Scalar(queryTableName, input)
	if err != nil || types.GetString(tbName) == "" {
		return 0, fmt.Errorf("表名不存在或查询失败,%v", err)
	}

	// 获取表字段
	columsFields, err := db.Query(inserColumnName, input)
	if err != nil || columsFields.IsEmpty() {
		return 0, errs.GetDBError(int64(columsFields.Len()), err)
	}
	//构建colums字段和values字段
	columns := make([]string, 0, columsFields.Len())
	values := make([]string, 0, columsFields.Len())
	for _, v := range columsFields {
		name := v.GetString("name")
		if _, ok := insertMap[name]; !ok {
			return 0, errs.NewError(406, "缺少字段"+name)
		}
		columns = append(columns, name)
		values = append(values, fmt.Sprintf("@%s", name))
	}
	if len(columns) == 0 {
		return 0, errs.NewError(406, "缺少添加字段")
	}

	// 构建查询语句
	insertDataSql := strings.Replace(insertSql, "{columns}", types.GetString(strings.Join(columns, ","), "1 = 1"), -1)
	insertDataSql = strings.Replace(insertDataSql, "{table_name}", types.GetString(tbName), -1)
	insertDataSql = strings.Replace(insertDataSql, "{values}", strings.Join(values, ","), -1)
	id, r, err := db.Executes(insertDataSql, insertMap)
	if r == 0 || err != nil {
		return 0, errs.GetDBError(int64(r), err)
	}
	return id, nil
}

func UpdateTableData(tenantID int, tableID int, insertMap types.XMap) (int64, error) {
	// 获取表名
	db := hydra.C.DB().GetRegularDB()
	input := map[string]interface{}{
		"table_id":  tableID,
		"tenant_id": tenantID,
	}

	// 获取表名
	tbName, err := db.Scalar(queryTableName, input)
	if err != nil || types.GetString(tbName) == "" {
		return 0, fmt.Errorf("表名不存在或查询失败,%v", err)
	}

	// 获取表字段
	columsFields, err := db.Query(updateColumnName, input)
	if err != nil || columsFields.IsEmpty() {
		return 0, errs.GetDBError(int64(columsFields.Len()), err)
	}
	//构建colums字段和values字段
	columns := make([]string, 0, columsFields.Len())
	conditions := make([]string, 0, 1)
	columnsMap := make(map[string]bool)
	for _, v := range columsFields {
		name := v.GetString("name")
		isPk := v.GetInt("is_pk", -1) == 1
		columnsMap[name] = isPk
	}

	//检查输入字段，并添加到columns和conditions字段中
	fmt.Printf("columns:%+v\n", columsFields)
	for k := range insertMap {
		if _, ok := columnsMap[k]; !ok {
			continue //跳过不存在的字段
		}
		if columnsMap[k] {
			conditions = append(conditions, fmt.Sprintf("&%s", k))
			continue //跳过主键字段，并添加到conditions中
		}
		//添加到columns中
		columns = append(columns, fmt.Sprintf("%s = @%s", k, k))
	}

	if len(conditions) == 0 {
		return 0, errs.NewError(406, "缺少主键")
	}
	if len(columns) == 0 {
		return 0, errs.NewError(406, "缺少更新字段")
	}

	// 构建查询语句
	updateDataSql := strings.Replace(updateSql, "{columns}", types.GetString(strings.Join(columns, ","), "1 = 1"), -1)
	updateDataSql = strings.Replace(updateDataSql, "{table_name}", types.GetString(tbName), -1)
	updateDataSql = strings.Replace(updateDataSql, "{condition}", strings.Join(conditions, ","), -1)
	id, _, err := db.Executes(updateDataSql, insertMap)
	if err != nil {
		return 0, err
	}
	return id, nil
}
